package com.xuan.yubi.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xuan.yubi.common.ErrorCode;
import com.xuan.yubi.exception.BusinessException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss.file")
public class FileUtils {

    private String aliDomain;

    private String accessKeyId;

    private String accessKeySecret;

    private String endPoint;

    private String bucketName;

    // 最大限制上传 2M 的图片
    private static final int FILE_MAX_SIZE = 2 * 1024 * 1024;


    public String uploadImage(MultipartFile file) {
        // 1. 先检查文件大小和文件是否为图片
        checkFileSizeAndIsImage(file);

        // 2. 生成文件名
        String originalFilename = file.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件名为空");
        }
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String date = DateUtils.getDate(new Date());
        String fileName = uuid + "-" + date + "-" + originalFilename;


        OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
        // 3. 将图片进行压缩
        try (InputStream inputStream = file.getInputStream()) {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            // 使用 Thumbnailator 压缩图片
            Thumbnails.of(inputStream).scale(1f).outputQuality(0.7f).toOutputStream(outputStream);
            byte[] bytes = outputStream.toByteArray();
            // 上传压缩后的图片到OSS
            InputStream compressedInputStream = new ByteArrayInputStream(bytes);

            // 3. 上传图片到阿里云对象存储服务
            ossClient.putObject(bucketName, fileName, compressedInputStream);
            if (!ossClient.doesObjectExist(bucketName, fileName)) {
                ossClient.putObject(bucketName, fileName, file.getInputStream());
            }
            // 仓库名 - 文件名 - 字节流
            compressedInputStream.close();
            return aliDomain + fileName;
        } catch (IOException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件上传失败");
        } finally {
            ossClient.shutdown();
        }
    }


    private void checkFileSizeAndIsImage(MultipartFile file) {
        String contentType = file.getContentType();
        long size = file.getSize();
        if (size > FILE_MAX_SIZE) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件过大,请上传小于 2M 的图片");
        }
        if (contentType != null && !contentType.startsWith("image/")) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "只能上传图片类型的文件");
        }
    }

}
